package com.macrolab.util;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.resource.loader.StringResourceLoader;
import org.apache.velocity.runtime.resource.util.StringResourceRepository;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * 模板工具类
 *
 * @author macroLu 2019-4-19
 */
public class VelocityUtil {
    String inputEncoding;
    String outputEncoding;
    VelocityContext context;

    public VelocityUtil() {
        //设置输入输出编码类型
        inputEncoding = "GBK";
        outputEncoding = "GBK";
        /* create a context and add data */
        context = new VelocityContext();
        context.put("myTools", new MyTools());
    }

    /**
     * 向velocity的context中放入变量对象
     *
     * @param name
     * @param obj
     */
    public void putObj(String name, Object obj) {
        context.put(name, obj);
    }

    /**
     * 由模板文件生成结果，调用前需先向context中绑定模板文件中使用的对象
     *
     * @param vmFilepath 模板文件
     * @return
     * @throws Exception
     */
    public String mergeByVMFile(String vmFilepath) {
        Properties p = new Properties();
        p.setProperty(Velocity.INPUT_ENCODING, inputEncoding);
        p.setProperty(Velocity.OUTPUT_ENCODING, outputEncoding);
        //这里加载类路径里的模板而不是文件系统路径里的模板
        p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader" );
        VelocityEngine ve = new VelocityEngine();
        ve.init(p);
        /* next, get the Template */
        Template t = ve.getTemplate(vmFilepath);

        /* now render the template into a StringWriter */
        StringWriter writer = new StringWriter();
        t.merge(context, writer);
        /* show the World */
        return writer.toString();
    }

    public String mergeByVMString(String template, String name, Object content) throws Exception {
        return mergeByVMString(template, name, content, null, null);
    }

    public String mergeByVMString(String template, String name, Object content, String inCharSet, String outCharSet) throws Exception {
        /* first, get and initialize an engine */
        Properties p = new Properties();
        //设置输入输出编码类型。
        if (null == inCharSet) {
            p.setProperty(Velocity.INPUT_ENCODING, inputEncoding);
        } else {
            p.setProperty(Velocity.INPUT_ENCODING, inCharSet);
        }
        if (null == outCharSet) {
            p.setProperty(Velocity.OUTPUT_ENCODING, outputEncoding);
        } else {
            p.setProperty(Velocity.OUTPUT_ENCODING, outCharSet);
        }
        //这里加载类路径里的模板而不是文件系统路径里的模板
        //通过String加载模板
        p.setProperty(VelocityEngine.RESOURCE_LOADER, "string" );
        p.setProperty("string.resource.loader.class", "org.apache.velocity.runtime.resource.loader.StringResourceLoader" );
        VelocityEngine ve = new VelocityEngine();
        ve.init(p);
        /* next, get the Template */
        //创建资源库
        StringResourceRepository repo = StringResourceLoader.getRepository();
        //模板资源存放 资源库 中
        repo.putStringResource(name, template);

        Template t = ve.getTemplate(name);

        /* now render the template into a StringWriter */
        StringWriter writer = new StringWriter();
        t.merge(context, writer);
        /* show the World */
        return writer.toString();
    }

    public String mergeByVMString(String template) {
        Properties p = new Properties();
        //设置输入输出编码类型。
        p.setProperty(Velocity.INPUT_ENCODING, inputEncoding);
        p.setProperty(Velocity.OUTPUT_ENCODING, outputEncoding);
        //这里加载类路径里的模板而不是文件系统路径里的模板
        //通过String加载模板
        p.setProperty(VelocityEngine.RESOURCE_LOADER, "string" );
        p.setProperty("string.resource.loader.class", "org.apache.velocity.runtime.resource.loader.StringResourceLoader" );
        VelocityEngine ve = new VelocityEngine();
        ve.init(p);

        StringWriter writer = new StringWriter();
        ve.evaluate(context, writer, "", template);
        /* show the World */
        return writer.toString();
    }


    public static void main(String[] args) throws IOException {

        VelocityUtil velocity = new VelocityUtil();
        List a = new ArrayList<String>();
        a.add("1" );
        a.add("2" );
        velocity.putObj("list", a);
        velocity.setInputEncoding("UTF-8");
        String content = velocity.mergeByVMFile("test.vm" );
        FileUtils.writeStringToFile(new File("d:/tmp/test.txt" ), content);
        System.out.print(content);
    }

    public String getInputEncoding() {
        return inputEncoding;
    }

    public void setInputEncoding(String inputEncoding) {
        this.inputEncoding = inputEncoding;
    }

    public String getOutputEncoding() {
        return outputEncoding;
    }

    public void setOutputEncoding(String outputEncoding) {
        this.outputEncoding = outputEncoding;
    }

}

